#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const https = require('https');
const { execSync } = require('child_process');
const os = require('os');

console.log('🚀 设置便携式Node.js环境...');

const platform = os.platform();
const arch = os.arch();

// Node.js版本配置
const NODE_VERSION = '18.19.0';
const projectRoot = __dirname;
const nodeDir = path.join(projectRoot, 'portable-node');

// 根据系统平台确定下载URL
function getNodeDownloadUrl() {
  let platformName, archName, fileExt;
  
  switch (platform) {
    case 'win32':
      platformName = 'win';
      archName = arch === 'x64' ? 'x64' : 'x86';
      fileExt = 'zip';
      break;
    case 'darwin':
      platformName = 'darwin';
      archName = arch === 'arm64' ? 'arm64' : 'x64';
      fileExt = 'tar.gz';
      break;
    case 'linux':
      platformName = 'linux';
      archName = arch === 'x64' ? 'x64' : 'armv7l';
      fileExt = 'tar.xz';
      break;
    default:
      throw new Error(`不支持的平台: ${platform}`);
  }
  
  const fileName = `node-v${NODE_VERSION}-${platformName}-${archName}`;
  return {
    url: `https://nodejs.org/dist/v${NODE_VERSION}/${fileName}.${fileExt}`,
    fileName: `${fileName}.${fileExt}`,
    extractedName: fileName
  };
}

// 下载文件
function downloadFile(url, destination) {
  return new Promise((resolve, reject) => {
    const file = fs.createWriteStream(destination);
    
    console.log(`📥 正在下载: ${url}`);
    
    https.get(url, (response) => {
      if (response.statusCode === 302 || response.statusCode === 301) {
        // 处理重定向
        return downloadFile(response.headers.location, destination);
      }
      
      if (response.statusCode !== 200) {
        reject(new Error(`下载失败: ${response.statusCode}`));
        return;
      }
      
      const totalSize = parseInt(response.headers['content-length'], 10);
      let downloadedSize = 0;
      
      response.on('data', (chunk) => {
        downloadedSize += chunk.length;
        const progress = ((downloadedSize / totalSize) * 100).toFixed(1);
        process.stdout.write(`\r📥 下载进度: ${progress}%`);
      });
      
      response.pipe(file);
      
      file.on('finish', () => {
        file.close();
        console.log('\n✅ 下载完成');
        resolve();
      });
      
      file.on('error', (err) => {
        fs.unlink(destination, () => {});
        reject(err);
      });
    }).on('error', reject);
  });
}

// 解压文件
function extractFile(filePath, extractPath, extractedName) {
  console.log('📦 正在解压文件...');
  
  try {
    if (filePath.endsWith('.zip')) {
      // Windows ZIP解压
      if (platform === 'win32') {
        execSync(`powershell -command "Expand-Archive -Path '${filePath}' -DestinationPath '${extractPath}' -Force"`, {
          stdio: 'inherit'
        });
      }
    } else if (filePath.endsWith('.tar.gz')) {
      // macOS tar.gz解压
      execSync(`tar -xzf "${filePath}" -C "${extractPath}"`, { stdio: 'inherit' });
    } else if (filePath.endsWith('.tar.xz')) {
      // Linux tar.xz解压
      execSync(`tar -xJf "${filePath}" -C "${extractPath}"`, { stdio: 'inherit' });
    }
    
    console.log('✅ 解压完成');
    
    // 重命名为统一的目录名
    const extractedPath = path.join(extractPath, extractedName);
    const targetPath = path.join(extractPath, 'node');
    
    if (fs.existsSync(extractedPath) && !fs.existsSync(targetPath)) {
      fs.renameSync(extractedPath, targetPath);
    }
    
  } catch (error) {
    throw new Error(`解压失败: ${error.message}`);
  }
}

// 创建启动脚本
function createPortableScripts() {
  const nodePath = platform === 'win32' 
    ? path.join(nodeDir, 'node', 'node.exe')
    : path.join(nodeDir, 'node', 'bin', 'node');
    
  const npmPath = platform === 'win32'
    ? path.join(nodeDir, 'node', 'npm.cmd')
    : path.join(nodeDir, 'node', 'bin', 'npm');

  // Windows批处理脚本
  if (platform === 'win32') {
    const batchScript = `@echo off
chcp 65001 >nul
echo 🚀 启动便携式文件传输工具...
echo.

set "NODE_PATH=${nodePath.replace(/\//g, '\\')}"
set "NPM_PATH=${npmPath.replace(/\//g, '\\')}"

if not exist "%NODE_PATH%" (
    echo ❌ Node.js 未找到，请先运行 setup-portable.bat
    pause
    exit /b 1
)

echo 📦 检查依赖包...
if not exist "node_modules" (
    echo 📥 安装依赖包...
    "%NPM_PATH%" install
)

echo 🔧 启动服务...
"%NODE_PATH%" start.js

pause
`;

    fs.writeFileSync('run-portable.bat', batchScript, 'utf8');
    
    const setupScript = `@echo off
chcp 65001 >nul
echo 🚀 设置便携式Node.js环境...
node setup-portable.js
pause
`;

    fs.writeFileSync('setup-portable.bat', setupScript, 'utf8');
    
  } else {
    // Unix Shell脚本
    const shellScript = `#!/bin/bash

echo "🚀 启动便携式文件传输工具..."
echo ""

NODE_PATH="${nodePath}"
NPM_PATH="${npmPath}"

if [ ! -f "$NODE_PATH" ]; then
    echo "❌ Node.js 未找到，请先运行 ./setup-portable.sh"
    exit 1
fi

echo "📦 检查依赖包..."
if [ ! -d "node_modules" ]; then
    echo "📥 安装依赖包..."
    "$NPM_PATH" install
fi

echo "🔧 启动服务..."
"$NODE_PATH" start.js
`;

    fs.writeFileSync('run-portable.sh', shellScript, 'utf8');
    fs.chmodSync('run-portable.sh', '755');
    
    const setupScript = `#!/bin/bash
echo "🚀 设置便携式Node.js环境..."
node setup-portable.js
`;

    fs.writeFileSync('setup-portable.sh', setupScript, 'utf8');
    fs.chmodSync('setup-portable.sh', '755');
  }
  
  console.log('✅ 便携式启动脚本已创建');
}

// 主安装函数
async function setupPortableNode() {
  try {
    // 检查是否已经安装
    const nodeExecutable = platform === 'win32' 
      ? path.join(nodeDir, 'node', 'node.exe')
      : path.join(nodeDir, 'node', 'bin', 'node');
      
    if (fs.existsSync(nodeExecutable)) {
      console.log('✅ 便携式Node.js已存在');
      createPortableScripts();
      return;
    }
    
    // 创建目录
    if (!fs.existsSync(nodeDir)) {
      fs.mkdirSync(nodeDir, { recursive: true });
    }
    
    // 获取下载信息
    const { url, fileName, extractedName } = getNodeDownloadUrl();
    const downloadPath = path.join(nodeDir, fileName);
    
    // 下载Node.js
    await downloadFile(url, downloadPath);
    
    // 解压
    extractFile(downloadPath, nodeDir, extractedName);
    
    // 清理下载文件
    fs.unlinkSync(downloadPath);
    
    // 创建启动脚本
    createPortableScripts();
    
    console.log('🎉 便携式Node.js环境设置完成！');
    console.log('');
    console.log('使用方法：');
    if (platform === 'win32') {
      console.log('  双击 run-portable.bat 启动项目');
    } else {
      console.log('  运行 ./run-portable.sh 启动项目');
    }
    
  } catch (error) {
    console.error('❌ 设置失败:', error.message);
    process.exit(1);
  }
}

// 运行安装
setupPortableNode(); 